<?php
abstract class MantaPackage extends MantaPage {
	var $directory;
	var $name;
	var $version;
	var $config;
	var $this;
	var $dependencies;
	var $is_running=false;

	function __construct() {
		//$this->dependencies = array("friendly"=>"","regex"=>array("
	}

	function is_running() {
		return $this->is_running;
	}

	function start() {
		$this->is_running = true;
		return true;
	}

	function stop() {
		$this->is_running = false;
		return true;
	}
	// TODO: implements interface
}

class MantaPackageManager {
	public $directory; // TODO: public?
	public $packages = array();
	public $name = "Package Manager"; // for the page
	protected $online_packages = array();
	protected $model;
	protected $tree;
	protected $description;

	function __construct() {
		$this->directory = p("packages");
		$this->load_packages();
		$this->load_packages_online();
	}

	function load_packages() {
		$this->packages = array();
		$files = glob($this->directory."/*/package.php");
		foreach ($files as $id => $file) {
			$id = substr($file, strlen($this->directory)+1, -12);
			dprint("Loading package $id");
			if (!@include_once($file)) {
				trigger_error("Package $id does not have a proper package manifest.", E_USER_WARNING);
				continue;
			}
			$classname = "Package$id";
			$this->packages[$id] = new $classname();
			$this->packages[$id]->directory = dirname($file); // This is pointless but used anyway.
		}
	}

	function load_packages_online() {
		$this->online_packages = array(
			"apache2"=>array(
				"display_name"=>"Apache 2",
				"version"=>array("remote"=>"2.2.52","local"=>"2.0.29"),
				"description"=>array("short"=>"Apache is a web server","long"=>"Blahdeblahdeblah blah, higgledepiggledy doo dah.  This package does something I'm sure, but I'm still not sure what.  This description is pointless, but please forgive me for that.\nThe quick brown fox jumps over the lazy dog.  Analysts are still uncertain as to its motivation.\n\n<i>Apples!?</i>  You must be <b>mad</b>!  Eat a <span color=\"yellow\"><b>b</b>a<b>n</b>a<b>n</b>a</span> a day to keep the doctor away :-)\n\n\n\"This is a trap for Poohs, and I'm waiting to fall in it.  'What's all this?' And then I say, 'it's a trap for Ho Hos, and I'm waiting for the Ho Ho Ho to come come.'\"\nHow long Piglet would have gone on like this I don't know, if Pooh hadn't suddenly woken up and decided it was 16...\n -- random pointless excerpt from Winnie the Pooh, by A. A. Milne, just to make this GtkLabel very long.  (Mostly accurate, but I typed it from memory :-)).\n\n* * *\n\nI'm sure we should have come to the end of the normal size by now."),
			),
			"php4"=>array(
				"display_name"=>"PHP 4",
				"version"=>array("remote"=>"4.4.18","local"=>"-"),
				"description"=>array("short"=>"PHP is a popular web development language","long"=>"Blahdeblahdeblah blah, higgledepiggledy doo dah.  This package does something I'm sure, but I'm still not sure what.  This description is pointless, but please forgive me for that."),
			),
			"php5"=>array(
				"display_name"=>"PHP 5",
				"version"=>array("remote"=>"5.2.3","local"=>"5.2.3"),
				"description"=>array("short"=>"PHP is a popular web development language","long"=>"Blahdeblahdeblah blah, higgledepiggledy doo dah.  This package does something I'm sure, but I'm still not sure what.  This description is pointless, but please forgive me for that."),
			),
		);
	}

	/*function &get_package($name) {
		if (isset($this->packages[$name])) {
			$value = &$this->packages[$name]; // TODO: '&'?
			return $value;
		} else
			return false;
	}

	function get_packages_id() {
		$packages_id = array();
		foreach ($this->packages as $id=>$pkg) {
			$packages_id[] = $id;
		}
		return $packages_id;
	}

	function &get_packages() {
		return $this->packages;
	}*/

	function create_frame() {
		$this->model = new GtkListStore(
			GObject::TYPE_PHP_VALUE,   // array containing everything
			GObject::TYPE_BOOLEAN,    //  selected
			GObject::TYPE_STRING,    //   id
			GObject::TYPE_STRING,   //    display name
			GObject::TYPE_STRING,  //     available version
			GObject::TYPE_STRING, //      installed version
			GObject::TYPE_STRING //       description
		);

		foreach ($this->online_packages as $id=>$package) {
			$this->model->append(array($package, false, $id, $package["display_name"], $package["version"]["remote"], $package["version"]["local"], $package["description"]["short"]));
		}

		$this->tree = new GtkTreeView($this->model);

		$r = new GtkCellRendererToggle();
		$r->set_property("activatable", true);
		$r->connect("toggled", array($this,"row_select_toggle"), $this->model);
		$this->tree->append_column(new MuiTVColumn("",                  $r,                        "active", 1));
		$this->tree->append_column(new MuiTVColumn("ID",                new GtkCellRendererText(), "text",   2));
		$this->tree->append_column(new MuiTVColumn("Name",              new GtkCellRendererText(), "text",   3));
		$this->tree->append_column(new MuiTVColumn("Available version", new GtkCellRendererText(), "text",   4));
		$this->tree->append_column(new MuiTVColumn("Installed version", new GtkCellRendererText(), "text",   5));
		$this->tree->append_column(new MuiTVColumn("Description",       new GtkCellRendererText(), "text",   6));
		$this->tree->get_selection()->connect("changed", array($this, "row_select_row"));

		$t = new MuiTable();
		$t->attach_simple(new MuiMarkupLabel("<b>Name:</b>"), 1, 1);
		$t->attach_simple(new MuiMarkupLabel("<b>Version:</b>"), 1, 2);
		$t->attach_simple(new MuiMarkupLabel("<b>Description:</b>"), 1, 3);
		$this->details_name = new MuiMarkupLabel();
		$this->details_version = new MuiMarkupLabel();
		$this->details_description = new MuiMarkupLabel();
		$t->attach_simple($this->details_name, 2, 1);
		$t->attach_simple($this->details_version, 2, 2);
		$t->attach_simple($this->details_description, 2, 3);

		return new MuiConfigPage(new MuiVPaned(new MuiScrollFrame($this->tree, false), new MuiScrollFieldset("Details", $t)), array($this, "save"));
	}

	function save() {
		not_implemented();
	}

	// The checkbox has been ticked on some row.  Update the value accordingly.
	function row_select_toggle($renderer, $iter, $model) {
		$iter = $model->get_iter($iter);
		$model->set($iter, 1, !$model->get_value($iter, 1));
	}

	// A row has been selected, so we need to update the details panel.
	function row_select_row($s) {
		list($model, $iter) = $s->get_selected();
		if (!$iter)
			return;

		$obj = $model->get_value($iter, 0);

		$this->details_name->set_markup($obj["display_name"]);
		$v = $obj["version"]["remote"];
		if ($obj["version"]["remote"]==$obj["version"]["local"])
			$v .= ' <span color="darkgreen">(up to date)</span>';
		elseif ($obj["version"]["local"] != "-")
			$v .= ' <span color="orange">(installed: '.$obj["version"]["local"].')</span>';
		else
			$v .= ' <span color="red">(not installed)</span>';
		$this->details_version->set_markup($v);
		$this->details_description->set_markup($obj["description"]["long"]);
	}
}
